#ifndef CIPODLIB_H_
#define CIPODLIB_H_

#include <list>
#include <string>
#include <stdlib.h>
#include <CIpodLibWrapper.h>

/************************************************************************
 * 版本信息
 ************************************************************************/

#define IPOD_LIB_VERSION    "V6.2.9"        // 版本号
#define IPOD_LIB_TIME       "2017.03.29"    // 版本时间

/************************************************************************
 * 类型定义
 ************************************************************************/
#ifdef __cplusplus
extern "C"{
#endif

//typedef signed char             int8;
//typedef signed short            int16;
//typedef signed long             int32;
//typedef signed long long        int64;
//typedef unsigned char           uint8;
//typedef unsigned short          uint16;
//typedef unsigned long           uint32;
//typedef unsigned long long      uint64;

//typedef unsigned int            ipod_t;

/************************************************************************
 * 状态定义
 ************************************************************************/
/**
 * IPOD模式
 */
typedef enum {
    Mode_MEDIA,
    Mode_CARLIFE,
    Mode_CARPLAY,
}IPODMode;

/**
 * IPOD模式
 */
typedef enum {
    ConnMode_UART,
    ConnMode_USB_HOST,
    ConnMode_USB_DEVICE,
    ConnMode_BLUETOOTH,
    ConnMode_WiFi,
    ConnMode_Hidg
}IPODConnMode;

/**
 * IPOD随机模式
 */
class IPODShuffleMode {
public:
    enum { OFF, SONGS, ALBUMS };
};

/**
 * IPOD重复模式
 */
class IPODRepeatMode {
public:
    enum { OFF, ONE, ALL };
};

/**
 * IPOD播放状态
 */
class IPODPlaybackState {
public:
    enum { STOPPED, PLAYING, PAUSED, SEEK_FORWARD, SEEK_BACKWARD, SEEKEND };
};

/**
 * IPOD媒体命令
 */
class IPODMediaCommand {
public:
    enum { PLAYPAUSE, PLAY, PAUSE, NEXT, PREVIOUS, SEEK_FORWARD, SEEK_BACKWARD, SEEKEND, SHUFFLE, REPEAT };
};

/**
 * IPOD列表目录
 */
class IPODCategoryType {
public:
    enum { ALL, PLAYLIST, ARTIST, ALBUM, GENRE, SONGS, COMPOSER, AUDIOBOOK, PODCAST, RADIO};
};

#if 0
/**
 * 播放状态上报消息
 * track_length     : 歌曲总长度
 * track_postion    : 播放进度
 * status           : 播放状态
 */
typedef struct {
    uint32              track_length;
    uint32              track_position;
    int                 state;
} IPODPlayStatus;
#endif

/**
 * 存储记录数据类型
 */
typedef struct _IPODMusicSource {
    uint32              index;
    uint64              id;
    std::string         name;
} IPODMusicSource;

/**
 * 音乐列表结构
 * size             : 列表长度
 * totalnum         : 当前层级下记录总数
 * start            : 开始序号
 * end              : 结束序号
 * level            : 列表所在层级, -1表示不支持层级跳转
 * elements         : 指向IPODMusicSource的指针
 * categorytype     : 当前层级的类型 {@see IPODCategoryType}
 */
typedef struct _IPODMusicList {
    uint32                      size;
    uint32                      totalnum;
    uint32                      start;
    uint32                      end;
    int32                       level;
    std::list<IPODMusicSource>  elements;
    int                         categorytype;
} IPODMusicList;

/************************************************************************
 * 回调接口
 ************************************************************************/
#if 0
/**
 * 连接状态变化
 */
typedef void (*onConnectStatusChanged)(ipod_t /*handle*/, bool /*connected*/);


/**
 * A2DP状态变化
 */
typedef void (*onA2dpStatusChanged)(ipod_t /*handle*/, bool /*connected*/);

/**
 * 采样率变化
 */
typedef void (*onSampleRateChanged)(ipod_t /*handle*/, int /*rate*/);

/**
 * 歌曲切换
 */
typedef void (*onTrackChanged)(ipod_t /*handle*/, uint32 /*index*/);

/**
 * 播放进度更新， new_position单位秒
 */
typedef void (*onTrackPositionChanged)(ipod_t /*handle*/, uint32 /*position*/);

/**
 * 歌曲时长更新， new_duration单位秒
 */
typedef void (*onTrackDurationChanged)(ipod_t /*handle*/, uint32 /*duration*/);

/**
 * 随机模式状态变化
 * mode: 模式 {@see IPODShuffleMode}
 */
typedef void (*onShuffleModeChanged)(ipod_t /*handle*/, int /*mode*/);

/**
 * 重复模式状态变化
 * mode: 模式 {@see IPODRepeatMode}
 */
typedef void (*onRepeatModeChanged)(ipod_t /*handle*/, int /*mode*/);

/**
 * 播放状态变化
 * state : 模式 {@see IPODPlaybackState}
 */
typedef void (*onPlaybackStateChanged)(ipod_t /*handle*/, int /*state*/);

/**
 * 专辑图片变化
 * path: 专辑图片路径，path为NULL时，表示当前歌曲没有专辑图片
 */
typedef void (*onAlbumArtworkChanged)(ipod_t /*handle*/, const char */*path*/);

/**
 * 媒体库更新进度
 * progress 0 ~ 100
 */
typedef void (*onMediaUpdateProgress)(ipod_t /*handle*/, uint8 /*progress*/);

/**
 * EA数据处理
 */
typedef void (*onEADataReceived)(uint8 */*data*/, uint16 /*len*/);

/**
 * EA Native状态变化
 */
typedef void (*onEANativeStateChanged)(int /*enabled*/);

/**
 * Device Information
 * name: Device Name
 */
typedef void (*onDeviceInformationChanged)(ipod_t /*handle*/, const char */*name*/);

/**
 * Music radio list file path
 */
typedef void (*onFileMusicRadioPath)(ipod_t /*handle*/, const char */*path*/);

/**
 * Music local device list file path
 */
typedef void (*onFileMusicLocalDevicePath)(ipod_t /*handle*/, const char */*path*/);

/**
 * 事件回调结构体
 */
typedef struct {
    onConnectStatusChanged      on_connect_status_changed;
    onA2dpStatusChanged         on_a2dp_status_changed;
    onSampleRateChanged         on_sample_rate_changed;
    onTrackChanged              on_track_changed;
    onTrackPositionChanged      on_track_position_changed;
    onTrackDurationChanged      on_track_duration_changed;
    onShuffleModeChanged        on_shuffle_mode_changed;
    onRepeatModeChanged         on_repeat_mode_changed;
    onPlaybackStateChanged      on_playback_state_changed;
    onAlbumArtworkChanged       on_album_artwark_changed;
    onMediaUpdateProgress       on_media_update_progress;
    onEADataReceived            on_ea_data_received;
    onEANativeStateChanged      on_ea_native_state_changed;
	onDeviceInformationChanged  on_device_information_changed;
    onFileMusicRadioPath        on_file_music_radio_path;
    onFileMusicLocalDevicePath  on_file_music_local_device_path;
} IPODObserver;
#endif

/************************************************************************
 * CLASS
 * 接口调用成功返回0，失败或不支持返回-1
 ************************************************************************/
class CIpodLib {
public:
    ~CIpodLib();
    static CIpodLib *getInstance();

    /**
     * 初始化libipod，例如配置、资源分配，此接口需要在使用时首先调用
     */
    int ipodLibInit(int mode, int connMode = ConnMode_USB_DEVICE);

    /**
     * 反初始化libipod，资源释放，此接口需要在退出时最后调用
     */
    int ipodLibDeinit();

    /**
     * 注册事件回调
     */
    void registerObserver(IPODObserver *observer);

    /**
     * 注销事件回调
     */
    void unregisterObserver();

    /**
     * 注册车机的蓝牙地址，用于通知蓝牙状态信息， 需要在connect之前调用
     * address: 蓝牙地址，字节数组，大小6
     */
    void notifyBtAddress(const uint8 *address);

    /**
     * 通知当前蓝牙连接状态
     */
    void notifyBtStatus(bool connected);

    /**
     * 创建链接
     * path：iPod设备文件路径（如"/dev/hidraw0"），选择默认的iPod设备时将path设为NULL
     */
    int connect(ipod_t *handle, const char *path = NULL);

    /**
     * 断开链接
     */
    int disconnect(ipod_t *handle);

    /**
     * 更新usb audio状态（仅支持iPhone5及以后的设备）
     */
    int notifyUSBAudioStatus(ipod_t handle, bool enabled);

    /**
     * 发送多媒体指令
     * command：命令 {@see IPODMediaCommand}
     */
    int sendMediaCommand(ipod_t handle, int command);
    int sendMediaCommandDown(ipod_t handle, int command);
    int sendMediaCommandUp(ipod_t handle, int command);
    int sendMediaCommandLibraryInfo(ipod_t handle, void * mediaInfo);
    int sendStartLocationInformation(ipod_t handle, int start);
    int sendStartDeviceTimeUpdate(ipod_t handle);
    int sendCallStateUpdateInfo(ipod_t handle, void * callStateInfo);

    /**
     * 设置正在播放的歌曲进度
     * position：单位秒
     */
    int setPlayingTrackPosition(ipod_t handle, uint32 position);

    /**
     * 获取随机模式
     * mode：{@see IPODShuffleMode}
     */
    int getShuffleMode(ipod_t handle, int *mode);

    /**
     * 获取重复模式
     * mode：{@see IPODRepeatMode}
     */
    int getRepeatMode(ipod_t handle, int *mode);

    /**
     * 获取正在播放歌曲的播放总时间
     */
    int getPlayingTrackDuration(ipod_t handle, int * duration);

    /**
     * 获取正在播放的歌曲名称
     */
    int getPlayingTrackTitle(ipod_t handle, std::string &title);

    /**
     * 获取正在播放的歌曲专辑
     */
    int getPlayingTrackAlbum(ipod_t handle, std::string &album);

    /**
     * 获取正在播放的歌曲表演者
     */
    int getPlayingTrackArtist(ipod_t handle, std::string &artist);

    /**
     * 获取正在播放的歌曲专辑图片
     */
    int getPlayingTrackAlbumArtwork(ipod_t handle);

    /**
     * 获取播放状态
     */
    int getPlayStatus(ipod_t handle, IPODPlayStatus *status);

    /**
     * 获取正在播放的歌曲序号属性
     * index ： 索引
     * count ： 总数
     */
    int getPlayingTrackInfo(ipod_t handle, int32 *index, uint32 *count);

    /**
     * 获取正在播放的歌曲章节属性
     * index ： 索引
     * count ： 总数
     */
    int getPlayingChapterInfo(ipod_t handle, int32 *index, uint32 *count);

    /**
     * 获取iPod是否支持层级跳转
     */
    int isListLevelSupported(ipod_t handle, bool *supported);

    /**
     * 重置列表，回到根目录
     * num：根目录包含item个数
     */
    int resetMusicList(ipod_t handle, uint32 *num);

    /**
     * 根据索引号打开音乐文件列表，位于歌曲目录时调用此方法可以播放index指向的音乐文件
     * index：列表中第几个, 当index为-1时表示返回上级列表
     * level：列表层级, 当index为-1时level对应设为-1；当iPod设备不支持层级跳转时level值无效，设为-1；level设为-1时，表示不进行层级跳转，即按顺序显示下一级列表。
     * num  ：最后一级列表包含item个数
     */
    int selectMusicList(ipod_t handle, int32 index, int32 level, uint32 *num);

    /**
     * 根据索引号打开正在播放列表，位于歌曲目录时调用此方法可以播放index指向的音乐文件
     * index：列表中第几个
     */
    int selectMusicPlayingList(ipod_t handle, int32 index);

    /**
     * 根据起始位置和读取长度获取音乐列表(C++接口)
     */
    int getMusicList(ipod_t handle, uint32 startIndex, uint32 readCount, IPODMusicList *musicList);

    /**
     * 根据起始位置和读取长度获取音乐列表(C接口)
     */
    int getMusicList_c(ipod_t handle, uint32 startIndex, uint32 readCount, C_IPODMusicList *musicList);

    /**
     * 根据起始位置和读取长度获取播放列表(C接口)
     */
    int getMusicPlayingList(ipod_t handle, uint32 startIndex, uint32 readCount, C_IPODMusicList *musicList);

    /**
     * 启动iPod端应用
     */
    int launchApp(ipod_t handle, const char *appBundleID);

    /**
     * 发送EA数据
     */
    int sendEAData(ipod_t handle, const uint8 *data, uint16 len);

    /**
     * 获取EA Native状态
     */
    int getEANativeState(ipod_t handle);

    /**
     * 发送Location information
     */
    int setLocationInformation(ipod_t handle,const char *sentence);

    /**
     * 发送wifi information
     */
    int wifiInformationSharing(WifiConfigurationInfo wifi_info);

    /**
     * 蓝牙RFCOMM数据接收处理函数
     */
    int ipod_BT_spp_data_pro(ipod_t handle, int cDataLen, const char * pData);

    /**
     * 定义WiFi数据接收处理函数
     */
    int sendWiFiData( ipod_t handle,int cDataLen, const char * pData );

    /**
     *	蓝牙spp连接状态改变通知函数
     */
    void ipod_bt_spp_state_change(BtSppState state);

    /**
     * 注册蓝牙数据发送函数
     */
    void ipodRegistBtSppSendData(BtSendData n_bt_spp_send_data);

    /**
     * 注册WiFi数据发送函数
     */
    void setWiFiDataCallback( WiFiDataCallback callback );

    /**
     * 发送carplay connection
     */
    int iap2CarPlayStartSession(ipod_t handle, int type);

    /**
     * 发送buletooth oob pair completion information
     */
    int iap2OOBBTPairingCompletionInformation(ipod_t handle,int resultCode );

    /**
     * 发送buletooth pair information
     */
    int iap2BluetoothPairingAccessoryInformation(ipod_t handle, const char * inPairingDataP192,const char * inPairingDataP256);

    /**
     * 发送buletooth pair status
     */
    int iap2BluetoothPairingStatus(ipod_t handle, int success, const char * cancelReason);

private:
    CIpodLib();
    static CIpodLib *p_Instance;
    static pthread_mutex_t p_InstanceLibMutex;
};

#ifdef __cplusplus
}
#endif

#endif /* CIPODLIB_H_ */
